package com.guang.demo3.config;

import com.guang.demo2.service.AccountService;
import com.guang.demo2.utils.TransactionManager;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


/**
 * @Description
 * @Author liguang
 * @Date 2023/08/01/22:39
 */
@Configuration
@ComponentScan(basePackages = "com.guang.demo2")
public class Demo3Config {

    @Bean
    public DataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource ds = new ComboPooledDataSource();
        ds.setDriverClass("com.mysql.cj.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc");
        ds.setUser("root");
        ds.setPassword("root");
        return ds;
    }

    @Bean
    public QueryRunner runner(DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    @Bean(name = "accountServiceProxy")
    public AccountService accountServiceProxy(AccountService accountService,TransactionManager txManager){
        return (AccountService) Proxy.newProxyInstance(
                accountService.getClass().getClassLoader(),
                accountService.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;
                        try {
                            //开启事务
                            txManager.startTransaction();
                            //调用目标对象的方法：执行转账
                            result = method.invoke(accountService, args);
                            //提交事务
                            txManager.commitAndClose();
                        } catch (Exception e) {
                            e.printStackTrace();
                            //回滚事务
                            txManager.rollbackAndClose();
                        }
                        return result;
                    }
                }
        );
    }
}
